package esmaltes.repository;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

//import org.hibernate.Criteria;
//import org.hibernate.Session;

public class RepositorioGenerico<T, ID extends Serializable> implements Serializable {

	private static final long serialVersionUID = 1L;

	@Inject
	private EntityManager manager;
	
	private Class<T> classePersistente;
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public RepositorioGenerico() {
		this.classePersistente = (Class) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}
	
	@SuppressWarnings("unchecked")
	public List<T> todos(String ordem) {
//		Session session = manager.unwrap(Session.class);
//		Criteria criteria = session.createCriteria(getClassePersistente());
//		return criteria.list();
		
//		Query query = manager.createNativeQuery("select * from advogado order by " + ordem, Advogado.class);
//		return query.getResultList();
		
		Query query = this.manager.createQuery("from " + getClassePersistente().getName() + " Order by " + ordem);
		return query.getResultList();
	}
	
	public void adicionar(T entidade) {
		EntityTransaction trx = this.manager.getTransaction();
		trx.begin();
		
		this.manager.persist(entidade);
//		this.manager.merge(entidade);
		
		trx.commit();
	}
	
//	public T guardar(T entidade) {
//		return manager.merge(entidade);
//	}
	
	public void guardar(T entidade) {
		EntityTransaction trx = this.manager.getTransaction();
		trx.begin();
		
		entidade = getManager().merge(entidade);
		
		trx.commit();
	}
	
	
	public void remover(T entidade) {
		EntityTransaction trx = this.manager.getTransaction();
		trx.begin();
		
		this.manager.remove(entidade);
		this.manager.flush();
		
		trx.commit();
		
	}

	public final T buscarPorChave(Integer codigo) {
		return (T) getManager().find(getClassePersistente(), codigo);
    }
	
	public EntityManager getManager() {
		return manager;
	}

	public Class<T> getClassePersistente() {
		return classePersistente;
	}

}